﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
 * 版权所有 (c) 2022 北京超维景生物科技有限公司 保留所有权利。
 * 
 * 创建者：huangyang
 * 电子邮箱：huangyang@tvscope.cn
 * 创建时间：2023/3/9 12:26:28
 * 版本：V1.0.0
 * 描述：
 *
 * ----------------------------------------------------------------
 * 修改人：
 * 时间：
 * 修改说明：
 *
 * 版本：V1.0.1
 *----------------------------------------------------------------*/
#endregion << 版 本 注 释 >>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ImageK.Java;
using ImageK.Process;

namespace ImageK.Gui
{
	/// <summary>
	/// Freehand region of interest or freehand line of interest
	/// </summary>
	public class FreehandRoi:PolygonRoi
    {
		public FreehandRoi(int sx, int sy, ImagePlus imp): base(sx, sy, imp)
		{
			if (ToolBar.getToolId() == ToolBar.FREEROI)
				type = FREEROI;
			else
				type = FREELINE;
			if (nPoints == 2) nPoints--;
		}

		protected override void grow(int sx, int sy)
		{
			if (subPixelResolution() && xpf != null)
			{
				growFloat(sx, sy);
				return;
			}
			int ox = offScreenX(sx);
			int oy = offScreenY(sy);
			if (ox < 0) ox = 0;
			if (oy < 0) oy = 0;
			if (ox > xMax) ox = xMax;
			if (oy > yMax) oy = yMax;
			if (ox != xp[nPoints - 1] + x || oy != yp[nPoints - 1] + y)
			{
				xp[nPoints] = ox - x;
				yp[nPoints] = oy - y;
				nPoints++;
				if (IJ.altKeyDown())
					wipeBack();
				if (nPoints == xp.Length)
					enlargeArrays();
				drawLine();
			}
		}

		private void growFloat(int sx, int sy)
		{
			double ox = offScreenXD(sx);
			double oy = offScreenYD(sy);
			if (ox < 0.0) ox = 0.0;
			if (oy < 0.0) oy = 0.0;
			if (ox > xMax) ox = xMax;
			if (oy > yMax) oy = yMax;
			double xbase = getXBase();
			double ybase = getYBase();
			if (ox != xpf[nPoints - 1] + xbase || oy != ypf[nPoints - 1] + ybase)
			{
				xpf[nPoints] = (float)(ox - xbase);
				ypf[nPoints] = (float)(oy - ybase);
				nPoints++;
				if (nPoints == xpf.Length)
					enlargeArrays();
				drawLine();
			}
		}

		void drawLine()
		{
			int x1, y1, x2, y2;
			if (xpf != null)
			{
				x1 = (int)Math.Round(xpf[nPoints - 2] + x);
				y1 = (int)Math.Round(ypf[nPoints - 2] + y);
				x2 = (int)Math.Round(xpf[nPoints - 1] + x);
				y2 = (int)Math.Round(ypf[nPoints - 1] + y);
			}
			else
			{
				x1 = xp[nPoints - 2] + x;
				y1 = yp[nPoints - 2] + y;
				x2 = xp[nPoints - 1] + x;
				y2 = yp[nPoints - 1] + y;
			}
			int xmin = Math.Min(x1, x2);
			int xmax = Math.Max(x1, x2);
			int ymin = Math.Min(y1, y2);
			int ymax = Math.Max(y1, y2);
			int margin = 4;
			if (lineWidth > margin && isLine())
				margin = lineWidth;
			if (ic != null)
			{
				double mag = ic.getMagnification();
				if (mag < 1.0) margin = (int)(margin / mag);
			}
			if (IJ.altKeyDown())
				margin += 20; // for wipeBack
			imp.draw(xmin - margin, ymin - margin, (xmax - xmin) + margin * 2, (ymax - ymin) + margin * 2);
		}

		public override void handleMouseUp(int screenX, int screenY)
		{
			if (state == CONSTRUCTING)
			{
				addOffset();
				finishPolygon();
			}
			state = NORMAL;
		}
	}
}
